import socket,sys,os
import select
from time import time, ctime
from threading import *

conn_client={}

mySocketReception=None
thReception=None
numPartie=0
numThread=0
listePartie=list()
listeJoueur=list()
listeThread=list()
port=0
JeuServeur=GestionduJeu()
class Serveur:
    
    def __init__(self):
        self.TAILLE_BLOC=1024 

        mySocketReception = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
        

        try: 
            mySocketReception.bind(('localhost',port))

        except socket.error:
            print "La liaison a echouee"
            sys.exit()
        
        #JeuServeur=GestionduJeu()
        while 1:
            mySocketReception.listen(5)

        # en attente qu'un client se connecte
            newsock, addr = mySocketReception.accept()
            print "connection entrante : %s:%d" % addr
         
            thReception=ThreadReception(newsock)
            thReception.start()
          
            it=thReception.getName()
            conn_client[it]=newsock
            
            JeuServeur.addThread(thReception.getName())           

        mySocketReception.close()
        mySocketEmission.close()
    

class ThreadReception(Thread):
     def __init__(self,connexion,numpartie=0,numjoueur=0):
         Thread.__init__(self)
         self.connexion=connexion
         #pour connaitre pour chaque thread
         #a quelle partie et quel joueur elle appartient
         self.npartie=numpartie
         self.njoueur=numjoueur
         self.emission=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
          
     #le run est le meme pour toutes les threads
     #les threads de tous les clients sont actives en meme temps
     def run(self):
         nom=self.getName()
         while 1:
              msgClient=self.connexion.recv(1024)
              print msgClient

              if msgClient=="clientPret":
                  try:
                      self.emission.connect(('localhost',port+1))
                  except socket.error:
                      print "La liaison a echouee"
                      sys.exit()

              if msgClient=="click":
                  #on test si c'est a se joueur de jouer
                  if self.npartie.getetat()==self.njoueur :
                      msg2=self.connexion.recv(1024)
                      msg2=msg2.split(",")
                      #endroit joueur : msg2[0]
                      #mine decouverte : msg2[1] = 0 ou 1
                      mine=self.npartie.majlistemine(msg2[1],self.njoueur)
                      for (i in self.partie.getlisteJ()):
                          if i!=self.njoueur
                          i.send("click")
                          i.send(msg2[0])
                          i.send("majmine")
                          i.send(mine)
                      a = self.npartie.tour()
                      for (i in self.partie.getlisteJ()):
                          if i==a:
                              i.send("joue")
                          else :
                              i.send("attend")
                          
              if (msgClient=="partie"):
                    msg2=self.connexion.recv(1024)
                    #creation de la partie
                    listePartie[numPartie]=Partie(msg2,self.emission)
                    #le joueur qui cree la partie est le joueur 1
                    self.njoueur=1
                    self.npartie=numPartie
                    #liste contenant les param de la partie
                    #creation de partie
                    numPartie+=1

              if (msgClient=="listePartiesEnAttente"):
                  n=0
                  c=""
                  for i in listePartie:
                      if i.getetat==-1:
                          #partie en attente de joueur
                          n+=1
                          c=c+";"+i.getinfo()
                  self.emission.send(n)
                  self.emission.send(c)

              if (msgClient=="numPartieChoisie"):
                  msg2=sock.recv(1024)
                  msg3=sock.recv(1024)
                  self.njoueur=listPartie[int(msg2)].addjoueur(msg3,self.emission)
                  self.npartie=int(msg2)

              if (msgClient=="matrice"):
                  msg2=sock.recv(1024)
                  self.npartie.emiMatrice(msg2)

              if (msgClient=="bombeDecouverte"):
                  a
              if (msgClient=="click"):
		

              if (msgClient=="partieGagnee"):


              if (msgClient=="partiePerdu"):
              
              #if not msgClient: break
              self.writeDate(sock)
	
        
class Partie :
    def __init__(self,partie,sock):
        #partie est le msg recu par le serveur tel quel
        partie=partie.split(",")
        #etat en attente de joueur
        self.etat=-1
        #etat contient le num du joueur qui doit jouer
        #-1 signifie qu'il n'y a pas assez de joueur
        #-2 signifie que la partie est perdue
        #-3 signifie que la partie est gagnée
        if len(partie)!=4 :
            print ("erreur des données")
        else:
        #nom de la partie:
            self.nomPartie=partie[0]
        #nombre joueurs max dans la partie
            self.nbjoueurs=partie[1]
        #difficulté
            self.difficulte=partie[2]
        #liste des joueurs
            self.nomjoueurs=list()
            self.nomjoueurs.append(partie[3])
        #liste des sockets des joueurs
            self.sockJ=list()
            self.sockJ.append(sock)
        #liste mine découverte
            self.listemines=[0]*self.nbjoueurs

    def addjoueur(self,joueur,sock):
        #ajoute un joueur a une partie
        #verification prealable
        if self.etat==-1 and len(self.nomjoueurs)<self.nbjoueurs :
            self.nomjoueurs.append(joueur)
            self.sockJ.append(sock)
            if len(self.nomjoueurs)==self.nbjoueurs:
                self.startPartie()
                #demarrer la partie
            for i in self.sockJ:
                i.send("nouveau joueur")
            #retourne le num du joueur ajouté
            return len(self.nomjoueurs)
        else :
            print("erreur partie deja en cours")

    def majlistemine(self,mine,joueur):
        #met a jour la liste de mine decouverte
        self.listemines[joueur]+=mine
        #envoie une chaine de caractere de mine
        chaine=""
        for i in self.listemines :
            chaine=chaine+","+str(i)
        return chaine

    def getetat(self):
        return self.etat
    
    def tour(self):
        #passe au joueur suivant
        if self.etat+1<=self.nbjoueurs:
            self.etat=self.etat+1
        else :
            self.etat=1
        self.sockJ[self.etat].send("toi")
        return self.etat

    def getinfo(self):
        chaine=self.nomPartie+","+str(self.nbjoueurs)+","+self.difficulte+","+str(len(self.nomjoueurs))
        #le nom des joueurs ne sert a rien !!
        return chaine

    def emiMatrice(self,sock,matrice):
        for i in self.sockJ:
            if i != sock :
                i.send("matrice")
                i.send(matrice)

    def startPartie(self):
        self.etat=1
        for i in self.sockJ:
            i.send("listeJoueursFinal")
            i.send(chaine)
        self.sockJ[1].send("toi")



if __name__=="__main__":
    import sys
    if len(sys.argv)<2:
        print "usage : %s <port>" % (sys.argv[0],)
        sys.exit(-1)
    port=int(sys.argv[1])
    Serveur()
